﻿using System;
using System.Collections.Generic;
using System.Linq;
using Headsight.BPMN2WF.BPMN.Schemas;

namespace Headsight.BPMN2WF.BPMN.Model
{
    /// <summary>
    /// <see cref="BPMNArgumentFactory"/> default implementation.
    /// </summary>
    public class BPMNArgumentFactoryImpl : BPMNArgumentFactory
    {
        public override IList<BPMNArgument> CreateArguments(tDefinitions tDefinitions, tProcess tProcess, BPMNProcessFactoryParams bpmnMFacParams)
        {
            var result = new List<BPMNArgument>();

            if (tProcess.property != null)
            {
                foreach (var each in tProcess.property)
                {
                    var itemDefinition =
                        (tItemDefinition) tDefinitions.Items.First(x => x.id == each.itemSubjectRef.Name);
                    // this is for sure not the final implementation but works for now
                    // and sufficient to get some more experience with "process parameters".
                    var typeString = String.Format("System.{0}", itemDefinition.structureRef.Name);
                    var type = typeof (String).Assembly.GetType(typeString);

                    result.Add(new BPMNArgument(each.id, type));
                }
            }

            return result;
        }

        public override IList<BPMNArgument> CreateArgumentsIn(tFlowElement flowNode)
        {
            var result = new List<BPMNArgument>();

            var tActivity = flowNode as tActivity;

            if (tActivity == null || tActivity.ioSpecification == null || tActivity.ioSpecification.dataInput == null)
            {
                return result;                
            }

            foreach (var each in tActivity.ioSpecification.dataInput)
            {
                var dataInputAssoc = tActivity.dataInputAssociation.First(x => x.targetRef == each.id);

                var assignemtn = dataInputAssoc.assignment[0];
                var from = assignemtn.from;
                var fromText = from.Text;

                var exp = (fromText != null && fromText.Length >= 1) ? fromText[0] : String.Empty;

                result.Add(new BPMNArgument(each.name, typeof(String), exp));
            }

            return result;
        }

        public override IList<BPMNArgument> CreateArgumentsOut(tFlowElement flowNode)
        {
            var result = new List<BPMNArgument>();

            var tActivity = flowNode as tActivity;

            if (tActivity == null || tActivity.ioSpecification == null || tActivity.ioSpecification.dataOutput == null)
            {
                return result;
            }

            foreach (var each in tActivity.ioSpecification.dataOutput)
            {
                var dataInputAssoc = tActivity.dataOutputAssociation.First(x => x.sourceRef[0] == each.id);

                result.Add(new BPMNArgument(each.name, typeof(String), dataInputAssoc.sourceRef[0]));
            }

            return result;
        }
    }
}